站点与 Xray 共用 443 反向代理 —— Nginx Stream

  网站域名访问与 3x-ui 中的 Xray 节点都需要使用 443 端口时,如果 Nginx 和 Xray 同时监听同一个公网 IP 的 443 端口,会发生端口冲突,导致网站无法访问或者 VLESS TLS / Reality 节点无法正常连接。

  本教程使用 Nginx stream + ssl_preread 作为公网 443 的统一入口,由 Nginx 在四层读取 TLS ClientHello 中的 SNI,但不解密代理节点流量,然后将不同 SNI 的连接转发到不同的本地服务,实现网站与 3x-ui/Xray 共用公网 443 端口。

  与 v2ray-agent 的 Xray fallback 方案不同,本教程中 公网 443 由 Nginx stream 监听,3x-ui 中使用 443 的 Xray 入站改为仅监听 127.0.0.1:443。客户端仍然连接服务器公网 IP 的 443 端口,127.0.0.1:443 只是服务器内部转发端口。

  教程示例环境:

  3x-ui / Xray → 公网 443 → 内部 127.0.0.1:443
  VLESS Reality Vision → 443
  VLESS TCP TCP/TLS Vision → 443 或其他独立端口
  Komari 面板 → https://komari.10181128.xyz127.0.0.1:8083
  OpenList 网盘 → https://alist.10181128.xyz127.0.0.1:5244
  PanSou 盘搜 → https://pansou.10181128.xyz127.0.0.1:8107
  服务器公网 IP → 69.63.216.218

  Reality 的 SNI 可以使用 www.amd.com、Amazon、Cloudflare 等不同目标域名,只要不与实际网站域名冲突,就会自动进入 default → Xray,无需每次修改 Nginx 配置。

准备工作

  1. 一台 Debian / Ubuntu 服务器,并获取服务器公网 IP。
  2. 公网 IP 已直接绑定到服务器网卡。
  3. 域名已解析到当前服务器。
  4. 3x-ui 已安装,并已创建 VLESS TLS / Reality 入站。
  5. Komari、OpenList、PanSou 等网站服务已安装并监听自己的内部端口。
  6. 系统 Nginx 已安装。
  7. 本教程示例中的公网 IP、域名和端口需要替换成自己的实际配置。

最终可以实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
浏览器 / 代理客户端

69.63.216.218:443

Nginx stream + ssl_preread

├── SNI = komari.10181128.xyz
│ ↓
│ 127.0.0.1:31302
│ ↓
│ Komari :8083

├── SNI = alist.10181128.xyz
│ ↓
│ 127.0.0.1:31303
│ ↓
│ OpenList :5244

├── SNI = pansou.10181128.xyz
│ ↓
│ 127.0.0.1:31304
│ ↓
│ PanSou :8107

└── 其他所有 SNI

127.0.0.1:443

Xray
TLS / Reality

一、部署 3x-ui 与 Komari、OpenList、PanSou

3x-ui 正常安装并创建 Xray 入站。

例如:

1
2
3
4
5
6
7
Reality:
端口 443
状态:启用

TLS:
端口 58587
状态:启用

Komari、OpenList、PanSou 使用 Docker 或系统服务运行,只监听各自的业务端口。例如:

1
2
3
Komari   -> 0.0.0.0:8083
OpenList -> 0.0.0.0:5244
PanSou -> 0.0.0.0:8107

如果 Docker 实际显示为容器内部端口映射,例如:

1
2
3
0.0.0.0:8083->25774/tcp
0.0.0.0:5244->5244/tcp
0.0.0.0:8107->80/tcp

也没有问题,后续 Nginx 只需要反代宿主机实际暴露的 8083 / 5244 / 8107

不要让 Docker 中的 Nginx、Caddy、Traefik 等容器再占用宿主机 80/443。

查看容器:

1
docker ps -a

查看端口:

1
ss -lntp | grep -E ':(80|443|8083|5244|8107|58587)\b'

在配置 443 共用之前,可能看到:

1
2
3
4
5
*:443      -> xray reality
*:58587 -> xray TCP/TLS
*:8083 -> docker-proxy
*:5244 -> docker-proxy
*:8107 -> docker-proxy

其中当前直接占用公网 443 的是 Xray。

二、确认公网 IP 是否直接绑定到服务器

本教程为了让:

1
2
69.63.216.218:443 -> Nginx
127.0.0.1:443 -> Xray

同时存在,需要公网 IP 确实是服务器本机地址。

执行:

1
ip -4 addr show | grep -F '69.63.216.218'

正常示例:

1
inet 69.63.216.218/32 brd 69.63.216.218 scope global eth0

说明公网 IP 已直接绑定到网卡,可以继续使用本教程的方案。

如果没有任何输出,说明服务器可能位于上游 NAT 后面。此时不要让 Nginx listen 公网IP:443,应改用:

1
2
Nginx  -> 0.0.0.0:443
Xray -> 127.0.0.1:32443

并将 stream 中的 default 改为 127.0.0.1:32443

三、检查 Nginx stream 与 ssl_preread

执行:

1
nginx -V 2>&1 | tr ' ' '\n' | grep stream

理想状态:

1
2
3
4
--with-stream
--with-stream_realip_module
--with-stream_ssl_module
--with-stream_ssl_preread_module

其中最关键的是:

1
2
--with-stream
--with-stream_ssl_preread_module

ssl_preread 可以在不终止 TLS 的情况下读取 ClientHello 中的 SNI,然后按域名进行四层 TCP 分流。

如果:

1
ls -l /usr/lib/nginx/modules/ngx_stream_module.so

没有文件,但 nginx -V 已经显示 --with-stream,说明 stream 已静态编译进 Nginx,属于正常情况,不需要再安装动态模块。

四、准备 Komari / OpenList / PanSou HTTPS 证书

假设三个网站域名分别为:

1
2
3
Komari   -> komari.10181128.xyz
OpenList -> alist.10181128.xyz
PanSou -> pansou.10181128.xyz

先确认域名已经解析到当前服务器公网 IP:

1
2
3
dig +short komari.10181128.xyz
dig +short alist.10181128.xyz
dig +short pansou.10181128.xyz

1. 如果 acme.sh 已经存在证书

分别检查:

1
2
3
openssl x509 \
-in /root/.acme.sh/komari.10181128.xyz_ecc/fullchain.cer \
-noout -subject -issuer -dates
1
2
3
openssl x509 \
-in /root/.acme.sh/alist.10181128.xyz_ecc/fullchain.cer \
-noout -subject -issuer -dates
1
2
3
openssl x509 \
-in /root/.acme.sh/pansou.10181128.xyz_ecc/fullchain.cer \
-noout -subject -issuer -dates

2. 如果还没有证书

使用 standalone 方式申请时需要保证 80 端口暂时空闲。若 Nginx 已经启动,可临时停止:

1
systemctl stop nginx

设置默认 CA:

1
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt

申请 Komari:

1
2
3
4
5
/root/.acme.sh/acme.sh --issue \
-d komari.10181128.xyz \
--standalone \
--keylength ec-256 \
--server letsencrypt

申请 OpenList:

1
2
3
4
5
/root/.acme.sh/acme.sh --issue \
-d alist.10181128.xyz \
--standalone \
--keylength ec-256 \
--server letsencrypt

申请 PanSou:

1
2
3
4
5
/root/.acme.sh/acme.sh --issue \
-d pansou.10181128.xyz \
--standalone \
--keylength ec-256 \
--server letsencrypt

3. 安装到 Nginx 独立证书目录

创建目录:

1
mkdir -p /etc/nginx/ssl

安装 Komari:

1
2
3
4
5
6
7
install -m 644 \
/root/.acme.sh/komari.10181128.xyz_ecc/fullchain.cer \
/etc/nginx/ssl/komari.10181128.xyz.crt

install -m 600 \
/root/.acme.sh/komari.10181128.xyz_ecc/komari.10181128.xyz.key \
/etc/nginx/ssl/komari.10181128.xyz.key

安装 OpenList:

1
2
3
4
5
6
7
install -m 644 \
/root/.acme.sh/alist.10181128.xyz_ecc/fullchain.cer \
/etc/nginx/ssl/alist.10181128.xyz.crt

install -m 600 \
/root/.acme.sh/alist.10181128.xyz_ecc/alist.10181128.xyz.key \
/etc/nginx/ssl/alist.10181128.xyz.key

安装 PanSou:

1
2
3
4
5
6
7
install -m 644 \
/root/.acme.sh/pansou.10181128.xyz_ecc/fullchain.cer \
/etc/nginx/ssl/pansou.10181128.xyz.crt

install -m 600 \
/root/.acme.sh/pansou.10181128.xyz_ecc/pansou.10181128.xyz.key \
/etc/nginx/ssl/pansou.10181128.xyz.key

检查:

1
ls -l /etc/nginx/ssl/

应该至少存在:

1
2
3
4
5
6
komari.10181128.xyz.crt
komari.10181128.xyz.key
alist.10181128.xyz.crt
alist.10181128.xyz.key
pansou.10181128.xyz.crt
pansou.10181128.xyz.key

网站 HTTPS 证书由内部 Nginx 使用。

如果 3x-ui 的 443 入站是 VLESS TLS,则 Xray TLS 节点自己的证书仍然在 3x-ui/Xray 中单独配置;Nginx stream 不会替 Xray 终止 TLS。

Reality 本身不需要普通网站 TLS 证书。

五、配置 Komari / OpenList / PanSou 内部 HTTPS

为了便于管理,三个网站统一写在:

1
nano /etc/nginx/conf.d/services.conf

如果之前已经单独创建了 /etc/nginx/conf.d/komari.conf,可以删除其中重复的 Komari server 块后,统一改用下面这个 services.conf;不要让两个配置文件同时存在相同的 server_name + listen 配置。

写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

# HTTP 统一跳转 HTTPS
server {
listen 80;
server_name
komari.10181128.xyz
alist.10181128.xyz
pansou.10181128.xyz;

return 301 https://$host$request_uri;
}

# ==================================================
# Komari
# 内部 HTTPS:127.0.0.1:31302
# 后端服务:127.0.0.1:8083
# ==================================================

server {
listen 127.0.0.1:31302 ssl;
server_name komari.10181128.xyz;

ssl_certificate /etc/nginx/ssl/komari.10181128.xyz.crt;
ssl_certificate_key /etc/nginx/ssl/komari.10181128.xyz.key;

ssl_protocols TLSv1.2 TLSv1.3;

location / {
proxy_pass http://127.0.0.1:8083;
proxy_http_version 1.1;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_read_timeout 3600s;
proxy_send_timeout 3600s;

client_max_body_size 1000m;
}
}

# ==================================================
# OpenList
# 内部 HTTPS:127.0.0.1:31303
# 后端服务:127.0.0.1:5244
# ==================================================

server {
listen 127.0.0.1:31303 ssl;
server_name alist.10181128.xyz;

ssl_certificate /etc/nginx/ssl/alist.10181128.xyz.crt;
ssl_certificate_key /etc/nginx/ssl/alist.10181128.xyz.key;

ssl_protocols TLSv1.2 TLSv1.3;

location / {
proxy_pass http://127.0.0.1:5244;
proxy_http_version 1.1;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_request_buffering off;

client_max_body_size 4000m;
}
}

# ==================================================
# PanSou
# 内部 HTTPS:127.0.0.1:31304
# 后端服务:127.0.0.1:8107
# ==================================================

server {
listen 127.0.0.1:31304 ssl;
server_name pansou.10181128.xyz;

ssl_certificate /etc/nginx/ssl/pansou.10181128.xyz.crt;
ssl_certificate_key /etc/nginx/ssl/pansou.10181128.xyz.key;

ssl_protocols TLSv1.2 TLSv1.3;

location / {
proxy_pass http://127.0.0.1:8107;
proxy_http_version 1.1;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

client_max_body_size 1000m;
}
}

测试:

1
nginx -t

启动并设置开机自启:

1
systemctl enable --now nginx

此时 Nginx 只监听:

1
2
3
4
0.0.0.0:80
127.0.0.1:31302
127.0.0.1:31303
127.0.0.1:31304

还没有接管公网 443,所以不会影响当前正在工作的 Xray 443。

1. 测试内部 Komari

1
2
3
4
5
curl -sk \
--resolve komari.10181128.xyz:31302:127.0.0.1 \
-o /dev/null \
-w 'HTTP %{http_code}\n' \
https://komari.10181128.xyz:31302/

2. 测试内部 OpenList

1
2
3
4
5
curl -sk \
--resolve alist.10181128.xyz:31303:127.0.0.1 \
-o /dev/null \
-w 'HTTP %{http_code}\n' \
https://alist.10181128.xyz:31303/

3. 测试内部 PanSou

1
2
3
4
5
curl -sk \
--resolve pansou.10181128.xyz:31304:127.0.0.1 \
-o /dev/null \
-w 'HTTP %{http_code}\n' \
https://pansou.10181128.xyz:31304/

正常一般会返回:

1
HTTP 200

部分应用如果自身有跳转,也可能返回 301 / 302

六、配置 Nginx stream 公网 443 分流

先备份 Nginx 主配置:

1
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-20260827

创建 stream 配置目录:

1
mkdir -p /etc/nginx/stream.d

创建:

1
nano /etc/nginx/stream.d/443.conf

写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
map $ssl_preread_server_name $backend_443 {
komari.10181128.xyz 127.0.0.1:31302;
alist.10181128.xyz 127.0.0.1:31303;
pansou.10181128.xyz 127.0.0.1:31304;

default 127.0.0.1:443;
}

server {
listen 69.63.216.218:443;

ssl_preread on;
proxy_pass $backend_443;

proxy_connect_timeout 5s;
proxy_timeout 3600s;
}

其中:

1
komari.10181128.xyz  127.0.0.1:31302;

表示网站流量进入 Komari 内部 HTTPS。

而:

1
default 127.0.0.1:443;

表示其他所有流量全部进入 Xray。

因此 Reality 的 SNI 无论是:

1
2
3
www.amd.com
www.amazon.com
www.cloudflare.com

都不需要额外写进 Nginx,自动走:

1
default → 127.0.0.1:443 → Xray

不要把 Reality 或 VLESS TLS 节点的 SNI 设置成 komari.10181128.xyzalist.10181128.xyzpansou.10181128.xyz,否则会被 Nginx 分流到对应的网站服务。

七、在 nginx.conf 中加载 stream 配置

查看:

1
cat /etc/nginx/nginx.conf

在整个 http {} 块结束后增加:

1
2
3
stream {
include /etc/nginx/stream.d/*.conf;
}

结构应为:

1
2
3
4
5
6
7
8
9
10
11
12
events {
worker_connections 1024;
}

http {
...
include /etc/nginx/conf.d/*.conf;
}

stream {
include /etc/nginx/stream.d/*.conf;
}

注意:

stream {} 必须与 http {} 同级,不能写进 http {} 内部。

检查:

1
nginx -t

如果成功,此时 先不要 reload Nginx

因为 Xray 仍可能监听:

1
*:443

如果现在让 Nginx 加载:

1
69.63.216.218:443

会与 Xray 当前的 0.0.0.0:443 冲突。

八、修改 3x-ui 的 443 入站监听地址

进入:

1
2
3
4
3x-ui
→ 入站
→ 编辑当前使用 443 的 VLESS 入站
→ 基础配置

如果当前是:

1
2
监听 IP:留空
端口:443

留空通常代表:

1
0.0.0.0:443

修改为:

1
2
监听 IP:127.0.0.1
端口:443

只修改监听 IP,不修改端口。

如果当前为 Reality:

1
2
3
4
安全:Reality
uTLS:chrome
目标:www.amd.com:443
SNI:www.amd.com

这些全部保持不变。

UUID、Flow、Private Key、Public Key、Short ID 也全部保持不变。

保存后检查:

1
ss -lntp | grep ':443'

应该看到:

1
127.0.0.1:443 -> xray

而不应再看到:

1
*:443 -> xray

只有使用 443 的 Xray 入站需要改成 127.0.0.1

例如另一个 TLS 入站为 58587,如果仍需要公网直接访问 58587,监听 IP 可以继续留空,无需修改。

核心规则:

1
2
3
4
5
Xray 入站端口 = 443
→ Listen IP = 127.0.0.1

Xray 入站端口 ≠ 443,且需要公网直连
→ Listen IP 可以留空

九、让 Nginx 接管公网 443 并测试

确认 Xray 已变为:

1
127.0.0.1:443

后执行:

1
nginx -t && systemctl reload nginx

然后:

1
ss -lntp | grep ':443'

最终理想状态:

1
2
69.63.216.218:443 -> nginx
127.0.0.1:443 -> xray

这就是本方案最关键的最终状态。

1. 测试 Komari

浏览器打开:

1
https://komari.10181128.xyz

或者:

1
2
3
4
curl -sk \
-o /dev/null \
-w 'HTTP %{http_code}\n' \
https://komari.10181128.xyz/

正常应返回:

1
HTTP 200

2. 测试 Reality / TLS

Clash Verge Rev 等客户端仍然连接:

1
2
服务器:69.63.216.218
端口:443

客户端无需改成内部端口。

如果 Komari、OpenList、PanSou、Reality、TLS 均正常,则说明 443 共用成功。

十、共用 443 成功后的端口状态

执行:

1
2
docker ps -a
ss -lntp | grep -E ':(80|443|31302|31303|31304|8083|5244|8107|58587)\b'

理想状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
69.63.216.218:443 -> nginx
127.0.0.1:443 -> xray

0.0.0.0:80 -> nginx

127.0.0.1:31302 -> nginx
127.0.0.1:31303 -> nginx
127.0.0.1:31304 -> nginx

0.0.0.0:8083 -> docker-proxy-komari
0.0.0.0:5244 -> docker-proxy-openlist
0.0.0.0:8107 -> docker-proxy-pansou

*:58587 -> xray

最终架构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
公网 443

Nginx stream

├── komari.10181128.xyz
│ ↓
│ 127.0.0.1:31302
│ ↓
│ Komari :8083

├── alist.10181128.xyz
│ ↓
│ 127.0.0.1:31303
│ ↓
│ OpenList :5244

├── pansou.10181128.xyz
│ ↓
│ 127.0.0.1:31304
│ ↓
│ PanSou :8107

└── default

127.0.0.1:443

Xray

十一、配置证书自动续期与 Nginx 开机自启

acme.sh 不应该只更新 /root/.acme.sh/ 中的原始证书,还需要在续期成功后自动部署到 /etc/nginx/ssl/

1. Komari

1
2
3
4
5
6
/root/.acme.sh/acme.sh --install-cert \
-d komari.10181128.xyz \
--ecc \
--key-file /etc/nginx/ssl/komari.10181128.xyz.key \
--fullchain-file /etc/nginx/ssl/komari.10181128.xyz.crt \
--reloadcmd "systemctl reload nginx"

2. OpenList

1
2
3
4
5
6
/root/.acme.sh/acme.sh --install-cert \
-d alist.10181128.xyz \
--ecc \
--key-file /etc/nginx/ssl/alist.10181128.xyz.key \
--fullchain-file /etc/nginx/ssl/alist.10181128.xyz.crt \
--reloadcmd "systemctl reload nginx"

3. PanSou

1
2
3
4
5
6
/root/.acme.sh/acme.sh --install-cert \
-d pansou.10181128.xyz \
--ecc \
--key-file /etc/nginx/ssl/pansou.10181128.xyz.key \
--fullchain-file /etc/nginx/ssl/pansou.10181128.xyz.crt \
--reloadcmd "systemctl reload nginx"

检查三个证书的部署路径:

1
2
grep -E "Le_RealKeyPath|Le_RealFullChainPath|Le_ReloadCmd" \
/root/.acme.sh/komari.10181128.xyz_ecc/komari.10181128.xyz.conf
1
2
grep -E "Le_RealKeyPath|Le_RealFullChainPath|Le_ReloadCmd" \
/root/.acme.sh/alist.10181128.xyz_ecc/alist.10181128.xyz.conf
1
2
grep -E "Le_RealKeyPath|Le_RealFullChainPath|Le_ReloadCmd" \
/root/.acme.sh/pansou.10181128.xyz_ecc/pansou.10181128.xyz.conf

Le_ReloadCmd 可能以 Base64 编码形式保存,这是正常现象。

检查 acme.sh cron:

1
crontab -l | grep acme.sh

确保 Nginx 开机启动:

1
2
3
systemctl enable nginx
systemctl is-enabled nginx
systemctl is-active nginx

正常:

1
2
enabled
active

十二、备份当前可用配置

成功后建议立即备份。

1
2
3
4
5
mkdir -p /root/3xui-443-backup
cp /etc/nginx/nginx.conf /root/3xui-443-backup/
cp -a /etc/nginx/stream.d /root/3xui-443-backup/
cp /etc/nginx/conf.d/services.conf /root/3xui-443-backup/
cp -a /etc/nginx/ssl /root/3xui-443-backup/

3x-ui 本身建议同时使用面板自带的 备份 / 导出数据库 功能备份入站、用户、订阅和面板设置。

十三、常见问题

1. Nginx reload 后提示 443 地址已被占用

检查:

1
ss -lntp | grep ':443'

如果仍然看到:

1
*:443 -> xray

说明 3x-ui 的 443 入站监听 IP 仍然留空或为 0.0.0.0,需要改成:

1
127.0.0.1

保存后再执行:

1
nginx -t && systemctl reload nginx

2. 为什么 Nginx 不能写 listen 0.0.0.0:443

因为本方案中 Xray 使用:

1
127.0.0.1:443

0.0.0.0:443 代表监听所有本地 IPv4 地址,其中也包括 127.0.0.1,会与 Xray 冲突。

因此公网 IP 直接绑定服务器时,应明确写:

1
listen 69.63.216.218:443;

这样可以同时存在:

1
2
69.63.216.218:443 -> nginx
127.0.0.1:443 -> xray

3. Reality 更换 AMD / Amazon / Cloudflare SNI 后是否要改 Nginx

不需要。

因为:

1
default 127.0.0.1:443;

会把除实际网站域名之外的其他 SNI 全部送给 Xray。

只有当 Reality SNI 与网站域名完全相同时才会冲突,例如不要设置:

1
2
3
Reality SNI = komari.10181128.xyz
Reality SNI = alist.10181128.xyz
Reality SNI = pansou.10181128.xyz

4. VLESS TLS 和 Reality 都能用 443 吗

可以。

如果只是有时 TLS 用 443、有时 Reality 用 443,则当前使用 443 的入站统一设置:

1
2
Listen IP = 127.0.0.1
Port = 443

Nginx 不关心内部是 TLS 还是 Reality。

如果 TLS 和 Reality 需要同时使用公网 443,则给它们分配不同内部端口,再按 SNI 分流,例如:

1
2
TLS     -> 127.0.0.1:31443
Reality -> 127.0.0.1:32443

5. Komari / OpenList / PanSou 内部测试正常,公网域名打不开

检查:

1
2
3
4
5
6
nginx -t
systemctl status nginx --no-pager
ss -lntp | grep ':443'
dig +short komari.10181128.xyz
dig +short alist.10181128.xyz
dig +short pansou.10181128.xyz

必须确认 DNS 指向当前公网 IP,并且 443 状态为:

1
2
公网IP:443       -> nginx
127.0.0.1:443 -> xray

6. Komari / OpenList / PanSou 证书文件不存在

例如:

1
cannot load certificate key "/etc/nginx/ssl/komari.10181128.xyz.key"

检查:

1
ls -l /etc/nginx/ssl/

三个域名都必须同时存在 .crt.key

1
2
3
4
5
6
komari.10181128.xyz.crt
komari.10181128.xyz.key
alist.10181128.xyz.crt
alist.10181128.xyz.key
pansou.10181128.xyz.crt
pansou.10181128.xyz.key

7. 证书续期后 Nginx 仍然使用旧证书

检查 acme.sh 是否已经把三个域名的安装路径分别指向:

1
2
3
4
5
6
7
8
/etc/nginx/ssl/komari.10181128.xyz.key
/etc/nginx/ssl/komari.10181128.xyz.crt

/etc/nginx/ssl/alist.10181128.xyz.key
/etc/nginx/ssl/alist.10181128.xyz.crt

/etc/nginx/ssl/pansou.10181128.xyz.key
/etc/nginx/ssl/pansou.10181128.xyz.crt

并设置续期后的:

1
systemctl reload nginx

8. 修改 Nginx 后必须执行什么

先:

1
nginx -t

只有显示语法检查成功后,才能:

1
systemctl reload nginx

9. 443 节点订阅里不能出现 127.0.0.1

127.0.0.1 只是 Xray 在服务器内部的监听地址。

客户端仍然必须连接:

1
2
服务器公网 IP / 公网域名
端口 443

如果 3x-ui 生成的分享链接或 Clash/Mihomo 订阅错误地出现 127.0.0.1,需要在 3x-ui 的 Host / 外部分享地址设置中指定公网 IP 或公网域名。

10. Komari / OpenList / PanSou 是否能通过当前配置获取真实访客 IP

本教程使用的是最简化的:

1
2
Nginx stream
→ 内部 Nginx HTTPS

stream 到内部 HTTPS 的连接通常表现为本机连接,因此本教程不以透传网站访客真实源 IP 为目标。

如果后端业务必须精确获得原始客户端 IP,需要另外设计 PROXY Protocol 或其他四层转发方式,不能在当前公共 stream server 上简单全局开启 PROXY Protocol,否则会同时影响 Xray 后端。

十四、以后新增其他网站的标准流程

假设新增:

1
new.10181128.xyz

后端服务:

1
127.0.0.1:8080

标准流程:

  1. DNS 将 new.10181128.xyz 解析到服务器公网 IP。

  2. 为域名申请 HTTPS 证书。

  3. 将证书安装到 /etc/nginx/ssl/

  4. 给网站分配新的内部 HTTPS 端口,例如 127.0.0.1:31305

  5. 创建新的 Nginx HTTPS server {},反代到 127.0.0.1:8080

  6. /etc/nginx/stream.d/443.conf 中增加:

    1
    2
    3
    4
    5
    6
    7
    8
    map $ssl_preread_server_name $backend_443 {
    komari.10181128.xyz 127.0.0.1:31302;
    alist.10181128.xyz 127.0.0.1:31303;
    pansou.10181128.xyz 127.0.0.1:31304;
    new.10181128.xyz 127.0.0.1:31305;

    default 127.0.0.1:443;
    }
  7. 检查:

    1
    nginx -t
  8. 重新加载:

    1
    systemctl reload nginx
  9. 测试:

    1
    https://new.10181128.xyz

新增网站不需要修改 3x-ui 的 443 Xray 入站。

十五、核心原则

旧 v2ray-agent fallback:

1
2
3
4
5
6
7
公网 443

Xray

fallback

Nginx

本教程 3x-ui + Nginx stream:

1
2
3
4
5
6
7
公网 443

Nginx stream

├── 网站 SNI → 内部 Nginx HTTPS → 网站服务

└── 其他 SNI → 127.0.0.1:443 → 3x-ui / Xray

核心原则:

1
2
3
4
5
6
7
8
9
公网 443 永远给 Nginx stream
使用 443 的 Xray 入站只监听 127.0.0.1:443
其他公网高位 Xray 入站可以继续留空监听 IP
业务网站使用独立的 127.0.0.1 内部 HTTPS 端口
Docker 业务容器不要直接占用宿主机 80/443
网站域名在 stream map 中显式指定
其他所有 SNI 使用 default 转发给 Xray
Reality 更换普通公网 SNI 不需要修改 Nginx
证书自动续期后只需要 reload Nginx

只要最终端口状态满足:

1
2
公网IP:443       -> nginx
127.0.0.1:443 -> xray

并且 Komari、OpenList、PanSou 网站域名以及 Reality / TLS 节点均可正常访问,即说明 3x-ui 与多个网站共用 443 端口配置成功。

站点与 Xray 共用 443 反向代理 —— Nginx Stream

https://10181128.xyz/2026/08/27/站点与Xray共用443反向代理-Nginx Stream/

发布于

2026-08-27

更新于

2026-08-28

许可协议

评论

:D 一言句子获取中...